package meb

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "github.com/stripe/stripe-go/v72"
    "github.com/stripe/stripe-go/v72/checkout/session"
    "vitepress-serve/internal/common/hgin"
    "vitepress-serve/internal/model"
    "github.com/mosongcc/gotool/gtime"
    "os"
    "time"
    "log/slog"  // 添加 slog 包
)

// StripeCheckoutArgs 定义创建支付会话的请求参数
type StripeCheckoutArgs struct {
    Amount    int64  `json:"amount"`    // 支付金额(美分)
    Currency  string `json:"currency"`  // 货币类型
    ProductId string `json:"productId"` // 商品ID
}

// VerifyPaymentArgs 验证支付状态的请求参数
type VerifyPaymentArgs struct {
    SessionID string `json:"sessionId"` // Stripe 会话 ID
}

// CreateCheckoutSession 创建支付会话
func (ctl *Controller) CreateCheckoutSession(ctx *gin.Context) (err error) {
    token := hgin.CtxToken(ctx)
    var args = hgin.ApiReq[StripeCheckoutArgs](ctx)

    // 1. 查询商品信息
    var product model.Product
    if err = ctl.db.Where("prod_id = ? AND status = ?", 
        args.ProductId, 
        model.ProductStatus_UP).First(&product).Error; err != nil {
        return fmt.Errorf("商品不存在或已下架")
    }

    // 2. 查询用户信息
    var user model.User
    if err = ctl.db.Where("uid = ?", token.Uid).First(&user).Error; err != nil {
        return fmt.Errorf("用户不存在")
    }

    // 3. 检查是否已经是永久会员
    if product.Type == model.ProductType_VIP_LONG {
        var existOrder model.Order
        if err = ctl.db.Where("uid = ? AND status = ? AND prod_type = ?",
            user.Uid,
            model.ORDER_STATUS_PAID,
            model.ProductType_VIP_LONG).First(&existOrder).Error; err == nil {
            return fmt.Errorf("您已经是永久会员")
        }
    }

    stripe.Key = os.Getenv("STRIPE_SECRET_KEY")

    // 4. 创建支付会话参数
    params := &stripe.CheckoutSessionParams{
        PaymentMethodTypes: stripe.StringSlice([]string{"card"}),
        LineItems: []*stripe.CheckoutSessionLineItemParams{
            {
                PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{
                    Currency: stripe.String("usd"),
                    ProductData: &stripe.CheckoutSessionLineItemPriceDataProductDataParams{
                        Name: stripe.String(product.ProdName),
                        Description: stripe.String(product.Intro),
                    },
                    UnitAmount: stripe.Int64(int64(product.UnitPrice)),
                },
                Quantity: stripe.Int64(1),
            },
        },
        Mode:       stripe.String(string(stripe.CheckoutSessionModePayment)),
        SuccessURL: stripe.String(os.Getenv("STRIPE_SUCCESS_URL") + "?session_id={CHECKOUT_SESSION_ID}"),
        CancelURL:  stripe.String(os.Getenv("STRIPE_CANCEL_URL")),
        ClientReferenceID: stripe.String(user.Uid),
    }

    // 如果有商品图片，才添加图片参数
    if product.Thumb != "" {
        params.LineItems[0].PriceData.ProductData.Images = stripe.StringSlice([]string{product.Thumb})
    }

    // 5. 创建支付会话
    s, err := session.New(params)
    if err != nil {
        return fmt.Errorf("创建支付会话失败: %w", err)
    }

    // 6. 创建订单记录
    now := gtime.NowF14()
    // Calculate timeout time
    timeoutTime := time.Now().Add(30 * time.Minute).Format("20060102150405")
    
    order := model.Order{
        OrderId:    s.ID,
        Uid:        user.Uid,
        Status:     model.ORDER_STATUS_PENDING,
        TxnDate:    now[:8],           // 交易日期，取当前时间前8位
        TxnAmt:     product.UnitPrice, // 使用商品单价
        Amount:     int64(product.UnitPrice), // Stripe金额
        Currency:   "USD",             // Stripe使用美元
        PayType:    model.PayType_STRIPE_CARD,
        PayNo:      s.ID,              // 支付会话ID
        PayTimeout: timeoutTime, // 使用正确的时间格式
        ProdId:     product.ProdId,
        ProdName:   product.ProdName,
        ProdNum:    1,
        ProdPrice:  product.UnitPrice,
        ProdType:   product.Type,
        ProdThumb:  product.Thumb,
        Domain:     ctx.Request.Host,
        Ip:         ctx.ClientIP(),
        Ctime:      now,
        Mtime:      now,
    }
    
    if err = ctl.db.Create(&order).Error; err != nil {
        return fmt.Errorf("创建订单失败: %w", err)
    }

    hgin.ApiRes(ctx, gin.H{
        "status": "1",
        "data": gin.H{
            "sessionId": s.ID,
            "url":      s.URL,
            "orderInfo": gin.H{
                "orderId":   order.OrderId,
                "amount":    order.TxnAmt,
                "currency": order.Currency,
                "product":   order.ProdName,
            },
        },
    })
    return nil
}

// GetSubscriptionStatus 获取用户订阅状态
func (ctl *Controller) GetSubscriptionStatus(ctx *gin.Context) (err error) {
    token := hgin.CtxToken(ctx)
    
    slog.Info("开始查询用户订阅状态", "uid", token.Uid)
    
    // 直接查询用户最新的已支付订单
    var order model.Order
    query := ctl.db.Where("uid = ? AND status = ? AND pay_type = ?", 
        token.Uid, 
        model.ORDER_STATUS_PAID,
        model.PayType_STRIPE_CARD).
        Order("pay_time DESC")
    
    // 打印SQL语句
    stmt := query.Statement
    slog.Info("执行SQL查询",
        "sql", stmt.SQL.String(),
        "vars", stmt.Vars,
    )
    
    if err = query.First(&order).Error; err != nil {
        slog.Info("未找到已支付订单",
            "uid", token.Uid,
            "error", err,
        )
        hgin.ApiRes(ctx, gin.H{
            "status": "1",
            "data": gin.H{
                "subscribed": false,
                "plan": "free",
                "expireTime": "",
            },
        })
        return nil
    }

    // 打印查询结果
    slog.Info("查询到订阅订单",
        "orderId", order.OrderId,
        "status", order.Status,
        "payTime", order.PayTime,
        "prodType", order.ProdType,
    )

    // 确定会员类型和过期时间
    var expireTime string
    switch order.ProdType {
    case model.ProductType_VIP_LONG:
        expireTime = "2099-12-31 23:59:59" // 永久会员
    case model.ProductType_VIP_YEAR:
        payTime, _ := time.Parse("20060102150405", order.PayTime)
        expireTime = payTime.AddDate(1, 0, 0).Format("2006-01-02 15:04:05")
    case model.ProductType_VIP_MONTH:
        payTime, _ := time.Parse("20060102150405", order.PayTime)
        expireTime = payTime.AddDate(0, 1, 0).Format("2006-01-02 15:04:05")
    case model.ProductType_VIP_DAYS:
        payTime, _ := time.Parse("20060102150405", order.PayTime)
        expireTime = payTime.AddDate(0, 0, 30).Format("2006-01-02 15:04:05")
    default:
        expireTime = ""
    }

    hgin.ApiRes(ctx, gin.H{
        "status": "1",
        "data": gin.H{
            "subscribed": true,
            "plan":       string(order.ProdType),
            "expireTime": expireTime,
            "orderInfo": gin.H{
                "orderId":   order.OrderId,
                "payTime":   order.PayTime,
                "amount":    order.TxnAmt,
                "currency":  order.Currency,
                "prodName":  order.ProdName,
                "prodType":  order.ProdType,
            },
        },
    })
    return nil
}

// VerifyPayment 验证支付状态
func (ctl *Controller) VerifyPayment(ctx *gin.Context) (err error) {
    var args = hgin.ApiReq[VerifyPaymentArgs](ctx)
    
    slog.Info("开始验证支付状态", "sessionId", args.SessionID)
    
    stripe.Key = os.Getenv("STRIPE_SECRET_KEY")
    
    // 获取支付会话
    s, err := session.Get(args.SessionID, nil)
    if err != nil {
        slog.Error("获取支付会话失败", 
            "error", err,
            "sessionId", args.SessionID,
        )
        return fmt.Errorf("获取支付会话失败: %w", err)
    }

    slog.Info("获取支付会话成功",
        "sessionId", args.SessionID,
        "paymentStatus", s.PaymentStatus,
        "status", s.Status,
    )

    // 查询订单
    var order model.Order
    if err = ctl.db.Where("order_id = ?", args.SessionID).First(&order).Error; err != nil {
        slog.Error("查询订单失败",
            "error", err,
            "sessionId", args.SessionID,
        )
        return fmt.Errorf("订单不存在")
    }

    slog.Info("查询到订单信息",
        "orderId", order.OrderId,
        "uid", order.Uid,
        "status", order.Status,
        "prodType", order.ProdType,
    )

    // 检查支付状态
    if s.PaymentStatus == "paid" || s.Status == "complete" {  // 添加 status 检查
        slog.Info("订单支付成功", 
            "orderId", order.OrderId,
            "paymentStatus", s.PaymentStatus,
            "status", s.Status,
        )

        // 更新订单状态
        now := gtime.NowF14()
        tx := ctl.db.Begin()
        slog.Info("开始更新订单状态", "orderId", order.OrderId)

        // 1. 更新订单状态
        updateFields := map[string]interface{}{
            "status":   model.ORDER_STATUS_PAID,
            "pay_time": now,
            "mtime":    now,
            "pay_type": model.PayType_STRIPE_CARD,
            "pay_no":   args.SessionID,
            "prod_type": order.ProdType,
        }

        if err = tx.Model(&order).Updates(updateFields).Error; err != nil {
            tx.Rollback()
            slog.Error("更新订单状态失败",
                "error", err,
                "orderId", order.OrderId,
                "updateFields", updateFields,
            )
            return fmt.Errorf("更新订单状态失败: %w", err)
        }

        slog.Info("订单状态更新成功",
            "orderId", order.OrderId,
            "newStatus", model.ORDER_STATUS_PAID,
            "payTime", now,
        )

        // 2. 计算会员到期时间
        var vipDate string
        payTime, _ := time.Parse("20060102150405", now)
        switch order.ProdType {
        case model.ProductType_VIP_LONG:
            vipDate = "20991231" // 永久会员
        case model.ProductType_VIP_YEAR:
            vipDate = payTime.AddDate(1, 0, 0).Format("20060102")
        case model.ProductType_VIP_MONTH:
            vipDate = payTime.AddDate(0, 1, 0).Format("20060102")
        case model.ProductType_VIP_DAYS:
            vipDate = payTime.AddDate(0, 0, 30).Format("20060102")
        default:
            vipDate = payTime.Format("20060102")
        }

        slog.Info("计算会员到期时间",
            "uid", order.Uid,
            "prodType", order.ProdType,
            "vipDate", vipDate,
        )

        // 更新用户会员状态
        userUpdateFields := map[string]interface{}{
            "type":     model.USER_TYPE_VIP,
            "vip_date": vipDate,
            "mtime":    now,
        }

        if err = tx.Model(&model.User{}).Where("uid = ?", order.Uid).Updates(userUpdateFields).Error; err != nil {
            tx.Rollback()
            slog.Error("更新用户状态失败",
                "error", err,
                "uid", order.Uid,
                "updateFields", userUpdateFields,
            )
            return fmt.Errorf("更新用户状态失败: %w", err)
        }

        slog.Info("用户会员状态更新成功",
            "uid", order.Uid,
            "type", model.USER_TYPE_VIP,
            "vipDate", vipDate,
        )

        if err = tx.Commit().Error; err != nil {
            slog.Error("提交事务失败",
                "error", err,
                "orderId", order.OrderId,
                "uid", order.Uid,
            )
            return fmt.Errorf("提交事务失败: %w", err)
        }

        slog.Info("支付验证和状态更新完成",
            "orderId", order.OrderId,
            "uid", order.Uid,
            "prodType", order.ProdType,
            "vipDate", vipDate,
        )

        hgin.ApiRes(ctx, gin.H{
            "status": "1",
            "data": gin.H{
                "status":  "success",
                "message": "支付成功",
            },
        })
        return nil
    }

    slog.Info("支付未完成",
        "sessionId", args.SessionID,
        "paymentStatus", s.PaymentStatus,
        "status", s.Status,
    )

    hgin.ApiRes(ctx, gin.H{
        "status": "0",
        "data": gin.H{
            "status": "failed",
            "message": "支付未完成",
        },
    })
    return nil
}

// Remove getPlanByProduct function as we're using ProdType directly